import pandas as pd
import numpy as np
from src.factor_agent.core.base_factor import BaseFactor
from src.data_agent.adapters import AkshareDataAdapter

class FundamentalFactor(BaseFactor):
    """基本面因子基类（向量化计算版）"""
    
    def __init__(self, name, financial_item, window=4):
        super().__init__(name)
        self.financial_item = financial_item
        self.window = window  # 财报期数
        
    def _get_financial_data(self, symbol):
        """从数据代理获取标准化财务数据"""
        adapter = AkshareDataAdapter()
        return adapter.get_financials(
            symbol=symbol,
            item=self.financial_item,
            periods=self.window
        )
        
    def calculate(self, symbols):
        """
        计算多标的因子值
        :param symbols: 标的代码列表
        :return: DataFrame 索引为日期，列为symbols，值为因子值
        """
        all_data = []
        
        for symbol in symbols:
            # 获取原始财务数据
            raw_data = self._get_financial_data(symbol)
            
            # 数据预处理
            processed = self._preprocess(raw_data)
            
            # 生成因子序列
            factor_series = self._compute_factor(processed)
            
            all_data.append(factor_series)
            
        return pd.concat(all_data, axis=1)

    def _preprocess(self, data):
        """财务数据预处理"""
        # 1. 填充缺失值（向前填充）
        data = data.ffill()
        
        # 2. 标准化处理（行业中性化）
        if hasattr(self, 'industry_class'):
            data = self._neutralize_industry(data)
            
        # 3. 离群值处理
        data = self._winsorize(data)
        
        return data

    def _neutralize_industry(self, data):
        """行业中性化处理"""
        # 获取行业分类数据
        industry = AkshareDataAdapter().get_industry_classification()
        
        # 合并行业数据
        merged = data.join(industry, how='left')
        
        # 按行业进行标准化
        return merged.groupby('industry').transform(
            lambda x: (x - x.mean()) / x.std()
        )

    def _winsorize(self, series, sigma=3):
        """3sigma去极值"""
        mean, std = series.mean(), series.std()
        upper = mean + sigma * std
        lower = mean - sigma * std
        return series.clip(lower, upper)

# 具体因子实现 --------------------------------------------------

class PE_Ratio(FundamentalFactor):
    """市盈率因子（TTM）"""
    def __init__(self):
        super().__init__(
            name="PE",
            financial_item="income",  # 利润表
            window=4
        )
        
    def _compute_factor(self, data):
        """(总市值 / 净利润TTM)"""
        market_cap = data['market_cap']  # 从行情数据获取
        net_profit = data['net_profit'].rolling(4).sum()  # 最近4季度求和
        return market_cap / net_profit

class ROE(FundamentalFactor):
    """净资产收益率（杜邦分析法）"""
    def __init__(self):
        super().__init__(
            name="ROE",
            financial_item="balance",  # 资产负债表
            window=4
        )
        
    def _compute_factor(self, data):
        """净利润 / 平均股东权益"""
        net_profit = data['net_profit']
        equity = data['total_equity']
        avg_equity = (equity + equity.shift(4)) / 2  # 年化平均
        return net_profit / avg_equity

class FinancialQuality(FundamentalFactor):
    """财务质量综合因子"""
    def __init__(self):
        super().__init__(
            name="FQ_Score",
            financial_item="cash_flow",  # 现金流量表
            window=8
        )
        
    def _compute_factor(self, data):
        """（经营现金流 + 自由现金流）/ 总负债"""
        op_cash = data['operating_cashflow'].rolling(4).sum()
        free_cash = data['free_cashflow'].rolling(4).sum()
        total_debt = data['total_liabilities']
        return (op_cash + free_cash) / total_debt